package com.shumi.rbac.service;

import com.shumi.enums.IReturnEnum;
import com.shumi.fun.DateFun;
import com.shumi.rbac.vo.TokenVO;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;

//import java.util.function.BiConsumer;

//import java.util.function.BiConsumer;


@Component
public class JwtTokenService {
    ReturnEnum returnEnum;

    @Value("${app.tokenTimeOut}")
    int tokenTimeOut;

    @Value("${app.tokenSignKey}")
    String tokenSignKey;

    @Getter
    HashMap<String, TokenVO> tokenMap;

    @PostConstruct
    void init(){
        tokenMap=new HashMap<>();
    }

    /**
     * 生成token
     * */
    public ReturnEnum generator(String logincode,Date loginDate){
       String token=getTokenByLogincode(logincode);
       if(token!=null){//已经登陆过的直接更新
            updateExpirationDate(token);
       }
        TokenVO tokenVO =generatorGI(logincode,loginDate);
        token= Jwts.builder().setClaims(tokenVO.toMap()).signWith(SignatureAlgorithm.HS256, tokenSignKey).compact();
        tokenMap.put(token, tokenVO);
        returnEnum=ReturnEnum.SUCCESS_1;
        returnEnum.returnObject=token;
        return returnEnum;
    }

    /**
     * 更新token的过期时间
     * */
    public void updateExpirationDate(String token){
        String logincode=tokenMap.get(token).getLoginCode();
        TokenVO tokenVO =generatorGI(logincode,null);
        tokenMap.put(token, tokenVO);
    }

    /**
     * todo 下个版本实现线程安全
     * 删除token
     * */
    public ReturnEnum destory(String token){
        Set<Map.Entry<String,TokenVO>> entries=tokenMap.entrySet();
        for (Iterator<Map.Entry<String,TokenVO>> it = entries.iterator(); it.hasNext();){
            Map.Entry<String,TokenVO> iterator=it.next();
            if(iterator.getKey().equals(token)){
                it.remove();
            }
        }
        returnEnum= ReturnEnum.SUCCESS_3;
        return returnEnum;
    }

    String getTokenByLogincode(String logincode){
        Set<String> iterator= tokenMap.keySet();
        for (Map.Entry<String,TokenVO> tmp :tokenMap.entrySet()){
            if(tmp.getValue().getLoginCode().equals(logincode)){
                return tmp.getKey();
            }
        }
        return null;
    }

    TokenVO generatorGI(String logincode, Date loginDate){
        Date currentDate=new Date();
        Date expirationDate=DateFun.addSecond(currentDate,tokenTimeOut);

        TokenVO tokenVO =new TokenVO();
        tokenVO.setLoginCode(logincode);
        if(loginDate!=null){
            tokenVO.setLoginDate(loginDate.getTime());
        }
        tokenVO.setUpdateDate(currentDate.getTime());
        tokenVO.setExpirationDate(expirationDate.getTime());
        return tokenVO;
    }

    @Getter
    public static  enum  ReturnEnum implements IReturnEnum {
        SUCCESS_1(10,"TOKEN生成成功",true),
        SUCCESS_2(11,"TOKEN更新成功",true),
        SUCCESS_3(12,"TOKEN注销成功",true),
        FAILED_1(12,"TOKEN生成失败",true)
        ;
        String code;
        String message;
        boolean success;
        Object returnObject;
        ReturnEnum(int code, String message, boolean success) {
            this.code=AuthService.class.getSimpleName()+"."+ code;
            this.message=message;
            this.success=success;
        }
    }
}
